//
// MTriangleSelector
//
package com.photoexpert;

import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

// MTriangleSelector is a class to select a triangle area from screen

class MTriangleSelector implements MouseListener, MouseMotionListener  {

    static MTriangleSelector Instance() {
        if(_instance == null) {
            _instance = new MTriangleSelector();
            Presentor.Instance().addMouseListener(_instance);
            Presentor.Instance().addMouseMotionListener(_instance);
        }
        return _instance;
    }

    void reset() {
        _mouseDown = false;
        _resizingPoint = RESIZING_POINT.NONE;
        if(_selection != null) {
            _selection.destroy();
            _selection = null;
        }
        _presentor.setCursor(Cursors._defaultCursor);
        App.Instance().selectionBecomeValid(false);
    }

    void initializeSelection() {
        if(_selection == null)
            _selection = new TriangleSelection();
        Dimension max = _presentor.getPreferredSize();
        _selection.setPoint1(max.width / 3, max.height / 3);
        _selection.setPoint2(max.width * 2 / 3, max.height / 3);
        _selection.setPoint3(max.width / 2, max.height * 2 / 3);
        _selection.startDrawBorder();
        App.Instance().selectionBecomeValid(true);
    }

    TriangleSelection getSelection() { return _selection; }

    void zoomRateChanged() {
        if(_selection != null)
            _selection.zoomRateChanged();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if(_presentor.getMouseMode() != Presentor.MOUSE_MODES.SELECTING_TRI)
            return;
        reset();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if(_presentor.getMouseMode() != Presentor.MOUSE_MODES.SELECTING_TRI)
            return;
        _mouseDown = true;
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if(_presentor.getMouseMode() != Presentor.MOUSE_MODES.SELECTING_TRI)
            return;
        _mouseDown = false;
    }

    @Override
    public void mouseEntered(MouseEvent e) { }

    @Override
    public void mouseExited(MouseEvent e) { }

    @Override
    public void mouseDragged(MouseEvent e) {
        if(_presentor.getMouseMode() != Presentor.MOUSE_MODES.SELECTING_TRI)
            return;
        if(_selection == null || _resizingPoint == RESIZING_POINT.NONE)
            return;
        Dimension max = _presentor.getPreferredSize();
        int x = e.getX();
        if(x < 0)
            x = 0;
        if(x > max.width - 1)
            x = max.width - 1;
        int y = e.getY();
        if(y < 0)
            y = 0;
        if(y > max.height - 1)
            y = max.height - 1;
        switch(_resizingPoint) {
            case POINT1 :
                _selection.setPoint1(x, y);
                break;
            case POINT2 :
                _selection.setPoint2(x, y);
                break;
            case POINT3 :
                _selection.setPoint3(x, y);
                break;
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        if(_presentor.getMouseMode() != Presentor.MOUSE_MODES.SELECTING_TRI)
            return;
        if(_selection == null)
            return;
        _resizingPoint = RESIZING_POINT.NONE;
        int x = e.getX();
        int y = e.getY();
        TriangleSelection.TPoint p1 = _selection.getPoint1();
        if(Math.abs(x - p1._x) < 5 && Math.abs(y - p1._y) < 5)
            _resizingPoint = RESIZING_POINT.POINT1;
        else {
            TriangleSelection.TPoint p2 = _selection.getPoint2();
            if(Math.abs(x - p2._x) < 5 && Math.abs(y - p2._y) < 5)
                _resizingPoint = RESIZING_POINT.POINT2;
            else {
                TriangleSelection.TPoint p3 = _selection.getPoint3();
                if(Math.abs(x - p3._x) < 5 && Math.abs(y - p3._y) < 5)
                    _resizingPoint = RESIZING_POINT.POINT3;
            }
        }
        if(_resizingPoint == RESIZING_POINT.NONE)
            _presentor.setCursor(Cursors._defaultCursor);
        else
            _presentor.setCursor(Cursors._moveCursor);
    }

    /* ------------------------------------------------------------------- */

    private MTriangleSelector() {
        _presentor = Presentor.Instance();
    }

    private enum RESIZING_POINT {
        NONE,
        POINT1,
        POINT2,
        POINT3
    }

    private static MTriangleSelector _instance = null;

    private Presentor               _presentor = null;
    private boolean                 _mouseDown = false;
    private RESIZING_POINT          _resizingPoint = RESIZING_POINT.NONE;
    private TriangleSelection       _selection = null;
}
